/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.gui.query;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

import nfse.gui.client.QueryService;
import nfse.gui.client.QueryServiceAsync;
import nfse.gui.client.NetFSEClient;
import nfse.gui.util.GUIUtil;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.gwtext.client.widgets.MessageBox;

public class SearchHistoryTab extends FlexTable {

    final FlexTable queryHistoryEntryTable = new FlexTable();

    private HashSet<String> checkedHistoryIDs = new HashSet<String>(10);

    NetFSEClient client = null;

    public SearchHistoryTab(NetFSEClient client) {
        this.client = client;

        FlexTable queryHistoryActionsTable = new FlexTable();

        Hyperlink queryHistoryDeleteButton = new Hyperlink("Delete", "DeleteSearchHistory");
        queryHistoryDeleteButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent sender) {
                Vector<String> temp = new Vector<String>();
                Iterator<String> it = checkedHistoryIDs.iterator();
                while (it.hasNext()) {
                    String qid = (String) it.next();
                    temp.addElement(qid);
                }

                if (temp.size() == 0) {
                    MessageBox.alert("You must select at least one Search History entry to delete.");
                    return;
                }

                String[] queryIDs = new String[temp.size()];
                for (int i = 0; i < queryIDs.length; i++) {
                    queryIDs[i] = (String) temp.elementAt(i);
                }
                deleteQueryHistories(queryIDs);
            }
        });

        Hyperlink queryHistoryRefreshButton = new Hyperlink("Refresh", "RefreshSearchHistory");
        // mergeButton.setText("Merge");

        queryHistoryRefreshButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent sender) {
                queryHistory();
            }
        });

        queryHistoryActionsTable.setWidget(0, 0, new Label("Actions: "));
        queryHistoryActionsTable.setWidget(0, 1, queryHistoryRefreshButton);
        queryHistoryActionsTable.setWidget(0, 2, new Label("|"));
        queryHistoryActionsTable.setWidget(0, 3, queryHistoryDeleteButton);

        this.setWidget(0, 0, queryHistoryActionsTable);
        this.setWidget(1, 0, queryHistoryEntryTable);

        queryHistory();
    }

    private synchronized void deleteQueryHistories(String[] queryIDs) {
        final String[] tempQueryIDs = queryIDs;
        String msg = "";
        if (queryIDs.length == 1) {
            msg = "Are you sure you want to delete the Search Histories for Search " + queryIDs[0] + "?";
        } else {
            msg = "The folowing Search Histories will be deleted: ";
            for (int i = 0; i < queryIDs.length; i++) {
                msg += queryIDs[i];
                if (i != queryIDs.length - 1) {
                    msg += ", ";
                }
            }
            msg += ".\n Are you sure you want to delete these Search History entries?";
        }

        MessageBox.confirm("Confirm", msg, new MessageBox.ConfirmCallback() {
            public void execute(String btnID) {
                if (btnID.equals("yes")) {
                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                    AsyncCallback callback = new AsyncCallback() {
                        public void onFailure(Throwable caught) {
                            NetFSEClient.redirectToHome();
                        }

                        public void onSuccess(Object result) {
                            Vector<String> temp = new Vector<String>();
                            Iterator<String> it = checkedHistoryIDs.iterator();
                            while (it.hasNext()) {
                                String qid = (String) it.next();
                                temp.addElement(qid);
                            }
                            for (int i = 0; i < temp.size(); i++) {
                                checkedHistoryIDs.remove(temp.elementAt(i));
                            }
                            queryHistory();
                        }
                    };

                    NetFSEService.multiQueryHistoryDelete(tempQueryIDs, callback);
                }
            }
        });

    }

    private synchronized void deleteQueryHistory(QueryOptions qo) {
        final QueryOptions tempQO = qo;
        MessageBox.confirm("Confirm", "Are you sure you want to delete Search History for Search " + qo.queryID + "?",
                new MessageBox.ConfirmCallback() {
                    public void execute(String btnID) {
                        if (btnID.equals("yes")) {
                            QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                            ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                            endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                            AsyncCallback callback = new AsyncCallback() {
                                public void onFailure(Throwable caught) {
                                    NetFSEClient.redirectToHome();
                                }

                                public void onSuccess(Object result) {
                                    queryHistory();
                                }
                            };

                            NetFSEService.deleteQueryOptions(tempQO.queryID, callback);
                        }
                    }
                });

    }

    public QueryOptions[] historyData;

    public QueryOptions[] getHistoryData() {
        return historyData;
    }

    public void setHistoryData(QueryOptions[] options) {
        this.historyData = options;
        // client.analysisContainerTab.buildHistoryTree();
    }

    public void queryHistory() {

        QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirectToHome();
            }

            public void onSuccess(Object result) {
                FlexTable.FlexCellFormatter formatter = queryHistoryEntryTable.getFlexCellFormatter();
                queryHistoryEntryTable.setStyleName("nfsetable");
                queryHistoryEntryTable.addStyleName("nfsetbody");

                int[] types = client.getAllTypes();

                // System.out.println("NUM TYPES: " + types.length);
                // for (int i = 0; i < types.length; i++)
                // System.out.println(types[i] + ": '" +
                // client.getTypeName(types[i]) + "'");

                while (queryHistoryEntryTable.getRowCount() > 0)
                    queryHistoryEntryTable.removeRow(0);

                QueryOptions[] options = (QueryOptions[]) result;
                setHistoryData(options);

                if (options != null && options.length > 0) {
                    if (queryHistoryEntryTable.getRowCount() <= 1) {

                        // queryHistoryEntryTable.setBorderWidth(1);
                        int idx = -1;
                        queryHistoryEntryTable.setHTML(0, ++idx, "");
                        queryHistoryEntryTable.setHTML(0, ++idx, "<b>Search ID</b>");
                        formatter.setWordWrap(0, idx, false);
                        // queryHistoryEntryTable.setHTML(0, ++idx,
                        // "<b>Actions</b>");
                        // formatter.setWordWrap(0, idx, false);
                        queryHistoryEntryTable.setHTML(0, ++idx, "<b>Submit TS</b>");
                        formatter.setWordWrap(0, idx, false);
                        // myQueriesOptionsTable.setHTML(0, ++idx, "<b>Append
                        // Query ID</b>");
                        // formatter.setWordWrap(0, idx, false);
                        queryHistoryEntryTable.setHTML(0, ++idx, "<b>Start TS</b>");
                        formatter.setWordWrap(0, idx, false);
                        queryHistoryEntryTable.setHTML(0, ++idx, "<b>End TS</b>");
                        formatter.setWordWrap(0, idx, false);
                        queryHistoryEntryTable.setHTML(0, ++idx, "<b>Search Criteria</b>");
                        formatter.setWordWrap(0, idx, false);
                        for (int i = 0; i < types.length; i++) {
                            // System.out.println(types[i] + ": '" +
                            // client.getTypeName(types[i]) + "'");
                            queryHistoryEntryTable.setHTML(0, ++idx, "<B>" + client.getTypeName(types[i]) + "</b>");
                            formatter.setWordWrap(0, idx, false);
                        }

                        queryHistoryEntryTable.getRowFormatter().setStyleName(0, "nfseth");

                    }

                    for (int i = 0; i < options.length; i++) {
                        int idx = -1;

                        if (i % 2 == 0)
                            queryHistoryEntryTable.getRowFormatter().setStyleName(i + 1, "nfsetr");
                        else
                            queryHistoryEntryTable.getRowFormatter().setStyleName(i + 1, "nfsetrodd");

                        // final String queryID = options[i].queryID;
                        // queryHistoryEntryTable.setHTML(i + 1, ++idx,
                        // options[i].queryID);
                        // formatter.setWordWrap(i + 1, idx, false);

                        final QueryOptions qo = options[i];

                        final CheckBox check = new CheckBox();
                        check.setValue(false);
                        if (checkedHistoryIDs.contains(qo.queryID)) {
                            check.setValue(true);
                        }
                        check.setName(qo.queryID);
                        check.addClickHandler(new ClickHandler() {
                            public void onClick(ClickEvent sender) {
                                if (check.getValue()) {
                                    checkedHistoryIDs.add(qo.queryID);
                                } else {
                                    checkedHistoryIDs.remove(qo.queryID);
                                }
                            }
                        });

                        FlexTable queryIDTable = new FlexTable();
                        queryIDTable.setStyleName("nospacing");
                        Hyperlink setLink = new Hyperlink("Set", "Set" + qo.queryID);
                        setLink.setHTML("Set");
                        setLink.addClickHandler(new ClickHandler() {
                            public void onClick(ClickEvent sender) {
                                client.setSearchCriteria(qo);
                                // tabs.selectTab(0);
                                // searchWindow.show();
                            }
                        });

                        Hyperlink deleteLink = new Hyperlink("Delete", "Delete" + qo.queryID);
                        deleteLink.addClickHandler(new ClickHandler() {
                            public void onClick(ClickEvent sender) {
                                deleteQueryHistory(qo);
                            }
                        });

                        queryIDTable.setHTML(0, 0, qo.queryID);
                        queryIDTable.setHTML(0, 1, "[");
                        queryIDTable.setWidget(0, 2, setLink);
                        queryIDTable.setHTML(0, 3, "]");

                        queryHistoryEntryTable.setWidget(i + 1, ++idx, check);
                        queryHistoryEntryTable.setWidget(i + 1, ++idx, queryIDTable);
                        formatter.setWordWrap(i + 1, idx, false);
                        formatter.addStyleName(i + 1, idx, "nfsetd");

                        queryHistoryEntryTable.setHTML(i + 1, ++idx, options[i].ts);
                        formatter.setWordWrap(i + 1, idx, false);
                        formatter.addStyleName(i + 1, idx, "nfsetd");

                        // String appendStr = "";
                        // if (options[i].appendQueryID.length() > 0)
                        // appendStr = options[i].appendQueryID;
                        // myQueriesOptionsTable.setHTML(i + 1, ++idx,
                        // appendStr);
                        // formatter.setWordWrap(i + 1, idx, false);

                        queryHistoryEntryTable.setHTML(i + 1, ++idx, options[i].startDate.toString());
                        formatter.setWordWrap(i + 1, idx, false);
                        formatter.addStyleName(i + 1, idx, "nfsetd");

                        if (options[i].endDate != null)
                            queryHistoryEntryTable.setHTML(i + 1, ++idx, options[i].endDate.toString());
                        else
                            queryHistoryEntryTable.setHTML(i + 1, ++idx, "");
                        formatter.setWordWrap(i + 1, idx, false);
                        formatter.addStyleName(i + 1, idx, "nfsetd");

                        String searchHTML = "";
                        if (options[i].queryType == GUIUtil.QUERY_TYPE_IPS) {
                            searchHTML = "IP Search: " + options[i].getIPsString();
                        } else if (options[i].queryType == GUIUtil.QUERY_TYPE_SEARCH) {
                            searchHTML = "General Search: " + options[i].getSearchString();
                        }
                        queryHistoryEntryTable.setHTML(i + 1, ++idx, searchHTML);
                        formatter.addStyleName(i + 1, idx, "nfsetd");

                        for (int x = 0; x < types.length; x++) { //
                            if (options[i].isSelected(types[x])) {
                                // System.out.println("Matched: " + types[x]);
                                queryHistoryEntryTable.setHTML(i + 1, ++idx, "<img src=\"image/checkmark.gif\">");
                            } else
                                queryHistoryEntryTable.setHTML(i + 1, ++idx, " ");
                            formatter.addStyleName(i + 1, idx, "tdcenter");
                            formatter.addStyleName(i + 1, idx, "nfsetd");
                        }

                        // System.out.println();
                    }

                } else {
                    while (queryHistoryEntryTable.getRowCount() > 0)
                        queryHistoryEntryTable.removeRow(0);
                    queryHistoryEntryTable.setHTML(0, 0, "No Search Histories currently stored in the database.");
                }
            }
        };

        nfseService.queryHistory(callback);
    }
}
